#include <allegro.h>
#include <stdio.h>

#define GFX_W 1280
#define GFX_H 720
#define NB_IMAGES 4

struct Perso {
	BITMAP * img_right[NB_IMAGES];
	BITMAP * img_left[NB_IMAGES];
	int x, y;
	int direction; 
};
typedef struct Perso Perso;
typedef struct
{ int x[100];
  int y[100];
  BITMAP *img;
	
}Coins;


       BITMAP *BackgroundN=NULL;
       BITMAP *BackgroundC=NULL;
       BITMAP *BackgroundQ=NULL;
 BITMAP *BackgroundS=NULL;
 BITMAP *BackgroundF=NULL;
int get_pixel(BITMAP* Buffer,int x,int y);



BITMAP* load_background_bmp(char chemin_background[]);
BITMAP* load_background1_bmp(char chemin_background_col[]);
void draw_background(BITMAP *Background,BITMAP*Buffer);
void destroy_background(BITMAP * Background);


void load_perso(Perso *perso);
void destroy_perso(Perso *perso);
void init_perso(Perso *perso);

void move_perso_right(Perso *perso,int *compteur,BITMAP * Background,int pix1);
void move_perso_left(Perso *perso,int *compteur,BITMAP * Background,int pix2);
void gravity_perso(Perso *perso,BITMAP * Background,int pix3);
void jump_perso(Perso *perso,BITMAP * Background,int pix4); 

void move_perso(Perso *perso,int *compteur,BITMAP * Background,int pix1,int pix2,int pix3,int pix4);
void draw_perso(Perso perso,BITMAP *Buffer, int compteur);
 int pause_jeux(BITMAP* BackgroundC,BITMAP* BackgroundS,BITMAP* BackgroundN,BITMAP *BackgroundQ,BITMAP* BackgroundF,BITMAP* Buffer,int *b,int *c);
int main() {
SAMPLE *music;
int son_music ;

	char chemin_background[]="./images/background.bmp";
        char chemin_background_col[]="./images/backgroundCol.bmp";
	BITMAP *Buffer;
	BITMAP *Background=NULL;
	BITMAP *BackgroundCol=NULL;

	Perso perso;
      
	int compteur;
 int pix1,pix2,pix3,pix4;
int a;
// int b,c,d,e;
	Coins *piece;
int key_down;
	allegro_init();
//INSTALL SOUND
if(install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL)) {
allegro_message("Sound Error: %s", allegro_error);
return 1;
}
//load music
music=load_wav("./son.wav");
if (!music) {
textprintf(screen,font,0,0,makecol(255,255,255),"error music ");
readkey();
return 0;
}
//Voulume SOUND
set_volume(255, 255);

//Play music
son_music=play_sample(music,128,128,1000,0) ;
	install_keyboard();
	set_color_depth(16);
	if (install_keyboard() == -1) {
		allegro_message("Error! %s", allegro_error);
		return (-1);
	}
	set_color_depth(24);
	if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, GFX_W, GFX_H, 0, 0) != 0) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); /* here’s the command for text mode */
		allegro_message("Unable to initialize video mode!\n%s\n", allegro_error);
		return (1);
	}


 a=0;
// b=0 ; c=0; d=0; e=0;
BackgroundN=load_bitmap("./images/imn.bmp", NULL);
BackgroundC=load_bitmap("./images/imc.bmp", NULL);
BackgroundQ=load_bitmap("./images/imq.bmp", NULL);
BackgroundS= load_bitmap("./images/ims.bmp", NULL);
BackgroundF= load_bitmap("./images/imf.bmp", NULL);
	
	
	Buffer = create_bitmap(SCREEN_W, SCREEN_H);
	//loading images
	//loading mario
	load_perso(&perso);
	//loading background + background collision
	Background=load_background_bmp(chemin_background);
	//loading background collision Map
 BackgroundCol=load_background1_bmp(chemin_background_col);
        
	//init position & direction
	compteur = 0;
	init_perso(&perso);
 
	while (a!=1) {
    if (key[KEY_ESC]){a=1;}
		
		clear_bitmap(Buffer);
		
		move_perso(&perso,&compteur,BackgroundCol,pix1,pix2,pix3,pix4);
		
		
               draw_background(BackgroundCol,Buffer);
               draw_background(Background,Buffer);
		
     
           pix1=get_pixel(BackgroundCol,perso.x+ perso.img_right[0]->w,perso.y + perso.img_right[0]->h /2);
         pix2=get_pixel(BackgroundCol,perso.x,perso.y + perso.img_left[0]->h /2);
pix3=get_pixel(BackgroundCol,perso.x+ perso.img_right[3]->w /2,perso.y);
pix4=get_pixel(BackgroundCol,perso.x+ perso.img_right[0]->w /2,perso.y + perso.img_right[0]->h);



		draw_perso(perso,Buffer,compteur);

/* if (key[KEY_P])
	{
	b=1;
	key_down=4;
	}
        if (b==1)
	{
	b=pause_jeux(&BackgroundC,&BackgroundS,&BackgroundN,&BackgroundQ,&BackgroundF,&Buffer,&b,&c);
	if (b==0)
	{key_down=1;}
	}


		//blit Buffer to screen
		blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);*/

		if (compteur == 10000)
			compteur = 0;
	}
	//destroy Mario
	destroy_perso(&perso);
	destroy_background(Background);
      destroy_background(BackgroundCol);
 destroy_background(BackgroundN);
destroy_background(BackgroundC);
destroy_background(BackgroundQ);
destroy_background(BackgroundS);
destroy_background(BackgroundF);
//destroy_coins(&piece);
	destroy_bitmap(Buffer);	
	return (0);
}
END_OF_MAIN();

/*
 * module background
 */



BITMAP* load_background_bmp(char chemin_background[])
{
	BITMAP* Background;

	Background=load_bitmap(chemin_background, NULL);
	if(Background == NULL){
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to load image !\n%s\n", allegro_error);
		return (NULL);
	}
	return (Background);

}
BITMAP* load_background1_bmp(char chemin_background_col[])
{
	BITMAP* BackgroundCol;

	BackgroundCol=load_bitmap(chemin_background_col, NULL);
	if(BackgroundCol == NULL){
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to load image !\n%s\n", allegro_error);
		return (NULL);
	}
	return (BackgroundCol);

}



void draw_background(BITMAP *Background,BITMAP*Buffer)
{
	blit(Background, Buffer, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
}

void destroy_background(BITMAP * Background)
{
	destroy_bitmap(Background);
}

/*
 * module mario
 */

void load_perso(Perso *perso)
{
	int i;
	char buf[50];
	for (i = 0; i < NB_IMAGES; i++) {
		sprintf(buf, "./images/right%d.bmp", i);
		perso->img_right[i] = load_bitmap(buf, NULL);
		sprintf(buf, "./images/left%d.bmp", i);
		perso->img_left[i] = load_bitmap(buf, NULL);
	}
}

void destroy_perso(Perso *perso)
{
	int i;
	for (i = 0; i < NB_IMAGES; i++) {
		destroy_bitmap(perso->img_right[i]);
		destroy_bitmap(perso->img_left[i]);
	}

}
void init_perso(Perso *perso)
{
	perso->direction = 0;
	perso->x = 1 ;
	perso->y = SCREEN_H -150;
}
void move_perso_right(Perso *perso,int *compteur,BITMAP * Background ,int pix1)
{

 

	if (key[KEY_RIGHT] && (perso->x < SCREEN_W - perso->img_right[0]->w)&& pix1 != 255) {
		*compteur+=1;

		(perso->x)+=1;
	perso->direction = 0; //right
	}

}

void move_perso_left(Perso *perso,int *compteur,BITMAP * Background,int pix2)
{

	if (key[KEY_LEFT] && (perso->x > 0 + perso->img_left[0]->w)&& pix2 != 255) {
		*compteur+=1;

		(perso->x)-=1;
		perso->direction = 1; //left
	}
}

void jump_perso(Perso *perso,BITMAP * Background,int pix3)
{

	if (key[KEY_UP] && pix3 != 255 )  {
		(perso->y)-=5;
		perso->direction = 2; //jump


	} 

}

void gravity_perso(Perso *perso,BITMAP * Background,int pix4)
{

       if ((key[KEY_DOWN] && perso->y <SCREEN_H-150 )&& pix4 != 255 )
     {
          (perso->y)+=2;
               perso->direction = 3;
}

}




void move_perso(Perso *perso,int *compteur,BITMAP * Background,int pix1,int pix2,int pix3,int pix4)
{
	move_perso_right(perso,compteur,Background,pix1);
	move_perso_left(perso,compteur,Background,pix2);
	jump_perso(perso,Background,pix3);
       gravity_perso(perso,Background,pix4);
	//add gravity
}
void draw_perso(Perso perso,BITMAP *Buffer, int compteur)
{
	static int last_direction; 

     
	if (perso.direction == 0){ //moving right

		draw_sprite(Buffer, perso.img_right[compteur % (NB_IMAGES-1) ],perso.x, perso.y);
		last_direction=0;
	}

	if(perso.direction == 1){ //moving left

		draw_sprite(Buffer, perso.img_left[compteur % (NB_IMAGES-1) ],perso.x, perso.y);
		last_direction=1;
	}
	if (perso.direction == 2 && last_direction==0 ) {	//jumping right

		draw_sprite(Buffer,perso.img_right[NB_IMAGES - 1],perso.x, perso.y);
	}
	if (perso.direction == 2 && last_direction==1) {	//jumping left

		draw_sprite(Buffer, perso.img_left[NB_IMAGES - 1],perso.x, perso.y);
	}
        if (perso.direction == 3 && last_direction==0) {	

		draw_sprite(Buffer, perso.img_right[NB_IMAGES - 4],perso.x,perso.y);
          }
       if (perso.direction == 3 && last_direction==1) {	

		draw_sprite(Buffer, perso.img_left[NB_IMAGES - 4],perso.x, perso.y);
          }

}

/*
 * module collision
 */
 

int get_pixel(BITMAP* Buffer,int x,int y)
{
	int tmp;
	tmp=getpixel(Buffer,x,y);
	return((getr(tmp) + getb(tmp) + getg(tmp)) / 3);
}

int pause_jeux(BITMAP* BackgroundC,BITMAP* BackgroundS,BITMAP* BackgroundN,BITMAP *BackgroundQ,BITMAP* BackgroundF,BITMAP* Buffer,int *b,int *c)
{
if (key[KEY_DOWN]){*c+=1;}
if (key[KEY_SPACE] && (*c % 5 ==1)){*b=0;return *b;}
if  (*c % 5 ==0){draw_sprite(Buffer,BackgroundN,70,70);}
if (*c % 5==1){draw_sprite(Buffer,BackgroundC,70,70);}
if (*c %5 ==2){draw_sprite(Buffer,BackgroundQ,70,70);}
if (*c %5==3){draw_sprite(Buffer,BackgroundS,70,70);}
if (*c %5==4){draw_sprite(Buffer,BackgroundF,70,70);}
readkey();
return *b;
}

void update_pos_coins(Coins *piece, int nbr_p,int step)
{
	int i;
	for(i=0;i<nbr_p;i++)
	{ piece->x[i]+=step;
	}
		
}
void supprimer_piece(int pos,Coins *piece,int *nbr_p)//
{int i;
 
 for(i=pos;i<(*nbr_p-1);i++)
 { piece->x[i]=piece->x[i+1];
   piece->y[i]=piece->y[i+1];
 }
 (*nbr_p)--;
}
void init_coins11(Coins *piece)
{ piece->img = load_bitmap("./images/piece.bmp",NULL);
  piece->x[0] = 1300;
  piece->y[0] = 400;
  
  piece->x[1] = 1400;
  piece->y[1] = 350;
  
  piece->x[2] = 1500;
  piece->y[2] = 400;
  
  piece->x[3] = 2800;
  piece->y[3] = 250;
  
  piece->x[4] = 3000;
  piece->y[4] = 150;
  
  piece->x[5] = 4800;
  piece->y[5] = 250;
  
  piece->x[6] = 5020;
  piece->y[6] = 150;
  
  piece->x[7] = 5310;
  piece->y[7] = 150;
  
  piece->x[8] = 5590;
  piece->y[8] = 150;
  
}
